﻿using System.Data.Common;
using System.Data.SqlClient;
using JetBrains.Annotations;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using MySql.Data.MySqlClient;
using Npgsql;
using static Abp.SequentialGuidGenerator;

namespace ARchGL.Platform.EntityFrameworkCore
{
    public static class HostDbContextConfigurer
    {
        public static void Configure(DbContextOptionsBuilder<HostDbContext> builder, string connectionString)
        {
            var type = DatabaseTypeHelper.GetDatabaseType(connectionString);
            if (type == SequentialGuidDatabaseType.MySql) builder.UseMySql(connectionString);
            else if (type == SequentialGuidDatabaseType.PostgreSql) builder.UseNpgsql(connectionString);
            else if (type == SequentialGuidDatabaseType.SqlServer) builder.UseSqlServer(connectionString);
        }

        public static void Configure(DbContextOptionsBuilder<HostDbContext> builder, DbConnection connection)
        {
            var type = DatabaseTypeHelper.GetDatabaseType(connection.ConnectionString);
            if (type == SequentialGuidDatabaseType.MySql) builder.UseMySql(connection);
            else if (type == SequentialGuidDatabaseType.PostgreSql) builder.UseNpgsql(connection);
            else if (type == SequentialGuidDatabaseType.SqlServer) builder.UseSqlServer(connection);
        }
    }

    public static class TenantDbContextConfigurer
    {
        public static void Configure(DbContextOptionsBuilder<TenantDbContext> builder, string connectionString)
        {
            var type = DatabaseTypeHelper.GetDatabaseType(connectionString);
            if (type == SequentialGuidDatabaseType.MySql) builder.UseMySql(connectionString);
            else if (type == SequentialGuidDatabaseType.PostgreSql) builder.UseNpgsql(connectionString);
            else if (type == SequentialGuidDatabaseType.SqlServer) builder.UseSqlServer(connectionString);
        }

        public static void Configure(DbContextOptionsBuilder<TenantDbContext> builder, DbConnection connection)
        {
            var type = DatabaseTypeHelper.GetDatabaseType(connection.ConnectionString);
            if (type == SequentialGuidDatabaseType.MySql) builder.UseMySql(connection);
            else if (type == SequentialGuidDatabaseType.PostgreSql) builder.UseNpgsql(connection);
            else if (type == SequentialGuidDatabaseType.SqlServer) builder.UseSqlServer(connection);
        }
    }

    //public static class DatabaseHelper
    //{
    //    public static SequentialGuidDatabaseType DatabaseType { get; set; }

    //    /// <summary>
    //    /// 获取当前数据库类型
    //    /// </summary>
    //    /// <param name="connection"></param>
    //    /// <returns></returns>
    //    public static SequentialGuidDatabaseType GetType(string connection)
    //    {
    //        if (DatabaseType > 0) return DatabaseType;

    //        var conn = connection.ToLowerInvariant();
    //        if (conn.Contains("host=") || conn.Contains("postgres"))
    //            return DatabaseType = SequentialGuidDatabaseType.PostgreSql;
    //        else if (conn.Contains("server=") || conn.Contains("root"))
    //            return DatabaseType = SequentialGuidDatabaseType.MySql;
    //        else if (conn.Contains("data source=") && conn.Contains("initial catalog="))
    //            return DatabaseType = SequentialGuidDatabaseType.SqlServer;

    //        return SequentialGuidDatabaseType.Oracle;
    //    }

    //    /// <summary>
    //    /// 执行原生 SQL 语句
    //    /// </summary>
    //    /// <param name="db"></param>
    //    /// <param name="sql"></param>
    //    /// <param name="parameters"></param>
    //    public static void Execute(this DbContext db, string sql, [NotNull] params object[] parameters)
    //    {
    //        var par = sql.Split('@');
    //        var obj = new object[par.Length - 1];

    //        for (int i = 1; i < par.Length; i++)
    //        {//组合 parameter 数组，主要是给列名加上 @ 符号
    //            var val = par[i];

    //            if (val.IndexOf(',') != -1)
    //                val = val.Split(',')[0];

    //            var length = val.IndexOf(' ');
    //            if (length == -1) length = val.Length;//兼容最后一个参数

    //            var parameterName = "@" + val.Trim().Substring(0, length);
    //            obj[i - 1] = GetParameter(parameterName, parameters[i - 1]);
    //        }

    //        if (DatabaseType == SequentialGuidDatabaseType.PostgreSql)
    //        {//当数据库是 PostgreSQL 时给每个字段加上双引号，因为 PostgreSQL 对大小写敏感
    //            var asdf = sql.Split('=');
    //            var symbol = ' ';
    //            foreach (var item in asdf)
    //            {
    //                var str = item;
    //                if (item.Contains(" IS NULL"))
    //                {//排除 NULL 语法
    //                    str = item.Replace("IS NULL", "");
    //                }
    //                symbol = ' ';
    //                var index = str.LastIndexOf(symbol);
    //                if (index == -1)
    //                {
    //                    symbol = ',';
    //                    index = str.LastIndexOf(symbol);
    //                    if (index == -1) continue;
    //                }
    //                var subsection = str.Trim().Split(symbol);
    //                var source = subsection[subsection.Length - 1].Replace("!", "");
    //                sql = sql.Replace(str, str.Replace(source, "\"" + source.Trim() + "\""));
    //            }
    //        }

    //        db.Database.ExecuteSqlCommand(sql, obj);
    //    }

    //    private static object GetParameter(string name, object par)
    //    {
    //        switch (DatabaseType)
    //        {
    //            case SequentialGuidDatabaseType.PostgreSql: return new NpgsqlParameter(name, par);
    //            case SequentialGuidDatabaseType.MySql: return new MySqlParameter(name, par);
    //            case SequentialGuidDatabaseType.SqlServer: return new SqlParameter(name, par);
    //            //case SequentialGuidDatabaseType.Oracle: return new OracleParameter(name, par);
    //            //case SequentialGuidDatabaseType.Sqlite: return new SqliteParameter(name, par);

    //            default: return new MySqlParameter(name, par);
    //        }
    //    }
    //}
}